package com.demo.arch.datapulsedemo.v2_pipeline.core;

import com.demo.arch.datapulsedemo.common.TaskResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 报表任务管道
 * 
 * 核心职责：
 * - 管理步骤执行顺序
 * - 统一异常处理
 * - 日志监控
 * 
 * 设计优势：
 * - 步骤自动装配（Spring注入）
 * - 按Order排序执行
 * - 支持幂等性（自动跳过已完成步骤）
 * 
 * @author DataPulse Team
 */
@Slf4j
@Component
public class ReportTaskPipeline {

  private final List<StepHandler> steps;

  /**
   * 构造函数：Spring自动注入所有StepHandler实现
   */
  @Autowired
  public ReportTaskPipeline(List<StepHandler> steps) {
    // 按Order排序
    this.steps = steps.stream()
        .sorted(Comparator.comparingInt(StepHandler::getOrder))
        .collect(Collectors.toList());

    log.info("Pipeline初始化完成，共{}个步骤:", this.steps.size());
    for (int i = 0; i < this.steps.size(); i++) {
      StepHandler step = this.steps.get(i);
      log.info("  步骤{}: {} (Order={})", i + 1, step.getName(), step.getOrder());
    }
  }

  /**
   * 执行完整流程
   * 
   * @param reportType 报表类型
   * @return 任务执行结果
   */
  public TaskResult execute(String reportType) {
    // 初始化上下文
    PipelineContext context = new PipelineContext(reportType);
    context.setTaskId(generateTaskId());

    log.info("========== V2 Pipeline 任务开始 ==========");
    log.info("任务ID: {}", context.getTaskId());
    log.info("报表类型: {}", reportType);
    log.info("执行步骤: {}", steps.stream().map(StepHandler::getName).collect(Collectors.joining(" → ")));

    long startTime = System.currentTimeMillis();

    try {
      // 依次执行每个步骤
      for (int i = 0; i < steps.size(); i++) {
        StepHandler step = steps.get(i);
        executeStep(step, context, i + 1);
      }

      long duration = System.currentTimeMillis() - startTime;
      log.info("========== V2 Pipeline 任务完成，耗时: {}ms ==========", duration);

      return TaskResult.success("Pipeline执行成功", context);

    } catch (Exception e) {
      long duration = System.currentTimeMillis() - startTime;
      log.error("========== V2 Pipeline 任务失败，耗时: {}ms ==========", duration, e);

      return TaskResult.fail("Pipeline执行失败: " + e.getMessage());
    }
  }

  /**
   * 执行单个步骤
   */
  private void executeStep(StepHandler step, PipelineContext context, int stepNumber) {
    log.info("--- 步骤{}/{}: {} ---", stepNumber, steps.size(), step.getName());

    // 幂等性检查
    if (!step.shouldExecute(context)) {
      log.info("--- 步骤{}: {} 已完成，跳过执行 ---", stepNumber, step.getName());
      return;
    }

    long startTime = System.currentTimeMillis();

    try {
      // 执行步骤
      step.handle(context);

      long duration = System.currentTimeMillis() - startTime;
      log.info("--- 步骤{}: {} 执行成功，耗时: {}ms ---", stepNumber, step.getName(), duration);

    } catch (StepExecutionException e) {
      log.error("--- 步骤{}: {} 执行失败 ---", stepNumber, step.getName());
      throw e;

    } catch (Exception e) {
      log.error("--- 步骤{}: {} 执行异常 ---", stepNumber, step.getName());
      throw new StepExecutionException(step.getName(), "未知异常", e);
    }
  }

  /**
   * 生成任务ID
   */
  private String generateTaskId() {
    return "TASK_V2_" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
  }

  /**
   * 获取所有步骤（供外部查询）
   */
  public List<StepHandler> getSteps() {
    return steps;
  }
}
